import Cocoa
import AVFoundation

class ManageWallpapersViewController: NSViewController, NSCollectionViewDataSource, NSCollectionViewDelegateFlowLayout {
    
    // MARK: - Properties
    private var allWallpapers: [URL] = []
    private var currentWallpapers: [URL] = []
    private let thumbnailCache = NSCache<NSURL, NSImage>()
    
    // Pagination
    private var currentPage = 0
    private let itemsPerPage = 9 // 3 items per row * 3 rows
    private var totalPages = 0
    
    // UI
    private var collectionView: NSCollectionView!
    private var prevButton: NSButton!
    private var nextButton: NSButton!
    private var pageLabel: NSTextField!
    
    // MARK: - Lifecycle
    override func loadView() {
        self.view = NSView(frame: NSRect(x: 0, y: 0, width: 900, height: 725))
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        loadWallpapers()
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleWallpaperHistoryChanged),
            name: .wallpaperHistoryChanged,
            object: nil
        )
    }
    
    // MARK: - UI Setup
    private func setupUI() {
        // Collection View
        let scrollView = NSScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(scrollView)
        
        let layout = NSCollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 10
        layout.minimumLineSpacing = 10
        layout.sectionInset = NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        
        collectionView = NSCollectionView()
        collectionView.collectionViewLayout = layout
        collectionView.register(WallpaperItem.self, forItemWithIdentifier: WallpaperItem.identifier)
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.backgroundColors = [.windowBackgroundColor]
        collectionView.isSelectable = true
        collectionView.allowsMultipleSelection = false
        
        scrollView.documentView = collectionView
        scrollView.hasVerticalScroller = true
        
        // Pagination Controls
        prevButton = NSButton(title: "上一页", target: self, action: #selector(goToPreviousPage))
        nextButton = NSButton(title: "下一页", target: self, action: #selector(goToNextPage))
        pageLabel = NSTextField(labelWithString: "")
        pageLabel.alignment = .center
        
        let paginationStack = NSStackView(views: [prevButton, pageLabel, nextButton])
        paginationStack.translatesAutoresizingMaskIntoConstraints = false
        paginationStack.orientation = .horizontal
        paginationStack.spacing = 20
        paginationStack.distribution = .gravityAreas
        view.addSubview(paginationStack)
        
        // Layout Constraints
        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: view.topAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            
            paginationStack.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 10),
            paginationStack.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            paginationStack.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10),
            paginationStack.heightAnchor.constraint(equalToConstant: 30)
        ])
    }
    
    // MARK: - Data Handling
    private func loadWallpapers() {
        allWallpapers = WallpaperManager.shared.getHistory()
        totalPages = Int(ceil(Double(allWallpapers.count) / Double(itemsPerPage)))
        if totalPages == 0 { totalPages = 1 } // At least one page
        
        // Ensure currentPage is valid after deletion
        if currentPage >= totalPages {
            currentPage = totalPages - 1
        }
        if currentPage < 0 { currentPage = 0 }
        
        updateCurrentPageData()
        restoreSelection()
    }
    
    private func updateCurrentPageData() {
        let startIndex = currentPage * itemsPerPage
        let endIndex = min(startIndex + itemsPerPage, allWallpapers.count)
        
        if startIndex >= allWallpapers.count {
            currentWallpapers = []
        } else {
            currentWallpapers = Array(allWallpapers[startIndex..<endIndex])
        }
        
        collectionView.reloadData()
        updatePaginationControls()
    }
    
    private func restoreSelection() {
        if let lastURL = WallpaperManager.shared.getLastSelectedWallpaper(),
           let index = currentWallpapers.firstIndex(of: lastURL) {
            let indexPath = IndexPath(item: index, section: 0)
            collectionView.selectItems(at: [indexPath], scrollPosition: [])
        }
    }
    
    @objc private func handleWallpaperHistoryChanged() {
        loadWallpapers()
        collectionView.reloadData()
    }
    
    // MARK: - Pagination Actions
    @objc private func goToPreviousPage() {
        if currentPage > 0 {
            currentPage -= 1
            updateCurrentPageData()
            restoreSelection()
        }
    }
    
    @objc private func goToNextPage() {
        if currentPage < totalPages - 1 {
            currentPage += 1
            updateCurrentPageData()
            restoreSelection()
        }
    }
    
    private func updatePaginationControls() {
        pageLabel.stringValue = "第 \(currentPage + 1) / \(totalPages) 页"
        prevButton.isEnabled = currentPage > 0
        nextButton.isEnabled = currentPage < totalPages - 1
    }
    
    // MARK: - CollectionView DataSource
    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
        return currentWallpapers.count
    }
    
    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
        let item = collectionView.makeItem(withIdentifier: WallpaperItem.identifier, for: indexPath) as! WallpaperItem
        let url = currentWallpapers[indexPath.item]
        item.textField?.stringValue = url.lastPathComponent
        item.removeHandler = { [weak self] in
            self?.removeWallpaper(url: url)
        }
        
        let isVideo = ["mov", "mp4"].contains(url.pathExtension.lowercased())
        item.setIsDynamic(isVideo)
        
        // Set if it's the current wallpaper
        let isCurrent = (url == WallpaperManager.shared.getLastSelectedWallpaper())
        item.setIsCurrent(isCurrent)
        
        if let cachedImage = thumbnailCache.object(forKey: url as NSURL) {
            item.imageView?.image = cachedImage
        } else {
            generateThumbnail(for: url) { [weak self, weak item] image in
                if let image = image {
                    item?.imageView?.image = image
                    self?.thumbnailCache.setObject(image, forKey: url as NSURL)
                }
            }
        }
        return item
    }
    
    // MARK: - CollectionView Delegate
    func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) {
        guard let indexPath = indexPaths.first else { return }
        let selectedURL = currentWallpapers[indexPath.item]
        
        // Avoid reloading if the same wallpaper is selected again
        if selectedURL == WallpaperManager.shared.getLastSelectedWallpaper() {
            return
        }
        
        WallpaperManager.shared.setLastSelectedWallpaper(url: selectedURL)
        NotificationCenter.default.post(name: .setWallpaper, object: nil, userInfo: ["url": selectedURL])
        
        // Reload to update the "current" indicator on all visible items
        collectionView.reloadData()
    }
    
    // MARK: - CollectionView FlowLayout Delegate
    func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize {
        let layout = collectionViewLayout as! NSCollectionViewFlowLayout
        let padding = layout.sectionInset.left + layout.sectionInset.right
        let spacing = layout.minimumInteritemSpacing * 2 // 2 gaps for 3 items
        let availableWidth = collectionView.bounds.width - padding - spacing - 1 // -1 for safety
        let itemWidth = floor(availableWidth / 3)
        let itemHeight = itemWidth * 0.75 // 4:3 aspect ratio + label height
        return NSSize(width: itemWidth, height: itemHeight)
    }
    
    // MARK: - Actions
    private func removeWallpaper(url: URL) {
        if WallpaperManager.shared.getLastSelectedWallpaper() == url {
            NotificationCenter.default.post(name: .clearWallpaper, object: nil)
        }
        WallpaperManager.shared.removeWallpaper(url: url)
    }
    
    private func generateThumbnail(for url: URL, completion: @escaping (NSImage?) -> Void) {
        DispatchQueue.global(qos: .userInitiated).async {
            let isVideo = ["mov", "mp4"].contains(url.pathExtension.lowercased())
            var finalImage: NSImage?
            
            if isVideo {
                let asset = AVURLAsset(url: url)
                let imageGenerator = AVAssetImageGenerator(asset: asset)
                imageGenerator.appliesPreferredTrackTransform = true
                if let cgImage = try? imageGenerator.copyCGImage(at: .zero, actualTime: nil) {
                    finalImage = NSImage(cgImage: cgImage, size: .zero)
                }
            } else {
                finalImage = NSImage(contentsOf: url)
            }
            
            DispatchQueue.main.async {
                completion(finalImage)
            }
        }
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

// MARK: - WallpaperItem Class
class WallpaperItem: NSCollectionViewItem {
    static let identifier = NSUserInterfaceItemIdentifier("WallpaperItem")
    var removeButton: NSButton!
    var removeHandler: (() -> Void)?
    private var dynamicLabelContainer: NSView!
    private var currentLabelContainer: NSView!
    
    override func loadView() {
        self.view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = NSColor.clear.cgColor
        view.layer?.cornerRadius = 8
        view.layer?.masksToBounds = true
        view.layer?.borderWidth = 0
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let containerView = NSView()
        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.wantsLayer = true
        containerView.layer?.backgroundColor = NSColor.controlBackgroundColor.cgColor
        containerView.layer?.cornerRadius = 8
        containerView.layer?.masksToBounds = true
        view.addSubview(containerView)
        
        let imageView = NSImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.layer?.masksToBounds = true
        imageView.imageScaling = .scaleAxesIndependently
        self.imageView = imageView
        containerView.addSubview(imageView)
        
        let label = NSTextField(labelWithString: "")
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = NSFont.systemFont(ofSize: 12)
        label.lineBreakMode = .byTruncatingMiddle
        self.textField = label
        containerView.addSubview(label)
        
        removeButton = NSButton(image: NSImage(systemSymbolName: "xmark.circle.fill", accessibilityDescription: "Remove")!, target: self, action: #selector(removeTapped))
        removeButton.translatesAutoresizingMaskIntoConstraints = false
        removeButton.isBordered = false
        removeButton.wantsLayer = true
        removeButton.contentTintColor = .red
        removeButton.layer?.cornerRadius = 9
        view.addSubview(removeButton)
        
        // --- Labels Setup ---
        dynamicLabelContainer = createLabelContainer(with: "动态壁纸")
        currentLabelContainer = createLabelContainer(with: "当前使用")
        
        // --- StackView for Labels ---
        let infoStackView = NSStackView(views: [currentLabelContainer, dynamicLabelContainer])
        infoStackView.translatesAutoresizingMaskIntoConstraints = false
        infoStackView.orientation = .vertical
        infoStackView.alignment = .leading
        infoStackView.spacing = 4
        view.addSubview(infoStackView)
        
        // --- Layout Constraints ---
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 4),
            containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -4),
            containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 4),
            containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -4),
            
            imageView.topAnchor.constraint(equalTo: containerView.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            
            label.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 8),
            label.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8),
            label.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -8),
            label.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -8),
            label.heightAnchor.constraint(equalToConstant: 14),
            
            removeButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 6),
            removeButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -6),
            removeButton.widthAnchor.constraint(equalToConstant: 18),
            removeButton.heightAnchor.constraint(equalToConstant: 18),
            
            infoStackView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 8),
            infoStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8),
            infoStackView.trailingAnchor.constraint(lessThanOrEqualTo: removeButton.leadingAnchor, constant: -8)
        ])
    }
    
    private func createLabelContainer(with text: String) -> NSView {
        let container = NSView()
        container.translatesAutoresizingMaskIntoConstraints = false
        container.wantsLayer = true
        container.layer?.backgroundColor = NSColor(white: 0.1, alpha: 0.3).cgColor
        container.layer?.cornerRadius = 8
        container.isHidden = true

        let label = NSTextField(labelWithString: text)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.backgroundColor = .clear
        label.textColor = .white
        label.font = .systemFont(ofSize: 10)
        label.alignment = .center
        label.isBezeled = false
        label.isEditable = false
        container.addSubview(label)

        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 6),
            label.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -6),
            label.topAnchor.constraint(equalTo: container.topAnchor, constant: 2),
            label.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -2)
        ])

        return container
    }
    
    override var isSelected: Bool {
        didSet {
            (view as? NSView)?.layer?.borderWidth = isSelected ? 3 : 0
            (view as? NSView)?.layer?.borderColor = isSelected ? NSColor.systemBlue.cgColor : nil
        }
    }
    
    func setIsDynamic(_ isDynamic: Bool) {
        dynamicLabelContainer.isHidden = !isDynamic
    }
    
    func setIsCurrent(_ isCurrent: Bool) {
        currentLabelContainer.isHidden = !isCurrent
    }
    
    @objc private func removeTapped() {
        removeHandler?()
    }
}
